function observe(data){
    if(!data || typeof data !== 'object') return;
    new Observer(data)

}

class Observer{
    constructor(value){
        this.value= value;
        this.walk(value) // walk 一个一个变成响应式
    }

    walk(obj){
        Object.keys(obj).forEach(key=>{
            defineReactive(obj, key, obj[key])
        })
    }
}

function defineReactive(obj, key, val){
    // 递归处理
    observe(val)
    Object.defineProperty(obj, key, {
       get (){
        //依赖收集
            Dep.target && dep.addDep(Dep.target)
 
           return val
       },
       set(newValue){
        if(val === newValue) return
        //
        dep.notify();//
       }
    })
}

class Vue{
    constructor(options){
        this.$options = options
        this.$data = options.data
        // 处理data变成响应式
        observe(this.$data)
    }
}

class Compile{
    constructor(el, vm){
        this.$vm = vm
        this.$el = document.querySelector(el)
        if(this.$el){
            this.compile(this.$el)
        }
    }
    compile(el){
        const  childNodes = el.childNodes
        Array.from(childNodes).forEach(node=>{
            if(this.isElement(node)){  //判断是否是元素节点
                console.log("编译元素"+node.nodeName);
                
                // this.compileElement(node
            }else if(this.isInter(node)){  //判断是不是文本
                console.log("编译文本"+node.textContent);
                // this.compileText(node)
            }
            if(node.childNodes && node.childNodes.length > 0){
                this.compile(node)
            }
        })
    }
}

class Watcher {
    constructor(vm, key,updater){
        this.vm = vm
        this.key = key
        this.updaterFn = updater
        
        Dep.target = this
        vm(key)
    }
}

class Dep{
    constructor(){
        this.dep = []
    }

    addDep(dep){
        if(!this.dep.includes(dep)){
            this.dep.push(dep)
        }
    }
}

const v = new Vue({
    el: '#app',
    template: `<input v-model = "msg" /> --- {{ msg}}`,
    data:{
        msg:"",
    },
   
})